home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.6 / subsample / subsample.c < prev    next >
C/C++ Source or Header  |  1999-09-11  |  6KB  |  185 lines

  1. /* 
  2.  * subsample.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* SUBSAMPLE:   program performs image subsampling after low-pass filtering
  10.  *                usage: subsample inimg outimg [-r subsample rate]
  11.  *                                     [-d DEGREE_FILTERING] [-q quickFlag] [-L]
  12.  */
  13.  
  14. #define DFLT_SUBRATE 2          /* subsample by 2 is default  */
  15. #define DFLT_DEG_FLTR 0.5       /* default degree of filtering */
  16. #define RECT_CUTOFF 0.443883    /* factor to calc. 3dB cutoff freq */
  17. #define GAUSS_CUTOFF 0.832555   /* factor to calc. 3dB cutoff freq */
  18. #define ROUNDUP 0.99999         /* for rounding up integer */
  19. #define NORM 1000.0             /* normaliz. factor to integerize */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <images.h>
  24. #include <tiffimage.h>
  25. #include <math.h>
  26. #include <string.h>
  27. extern void print_sos_lic ();
  28.  
  29. long convolve1r (Image *, Image *, long *, long, long);
  30. long smoothr (Image *, Image *, long, long);
  31. long input (int, char **, long *, double *, short *);
  32. long usage (short);
  33.  
  34. main (argc, argv)
  35.      int argc;
  36.      char *argv[];
  37. {
  38.   Image *imgI, *imgO;           /* input, output image structures */
  39.   long width, height;           /* image size */
  40.   double cutoff;                /* low-pass cutoff frequency */
  41.   long fltrSize;                /* filter mask size */
  42.   long rSubsample;              /* subsample rate */
  43.   double degFltr;               /* degree of filtering [0.0 - 1.0] */
  44.   double stdDev;                /* std. deviation param. of Gaussian */
  45.   long *fltr;                   /* 1D filter mask */
  46.   long midFltr;                 /* middle filter coefficient */
  47.   short quickFlag;              /* for quick and dirty rect. filter */
  48.   long i;
  49.  
  50.   if (input (argc, argv, &rSubsample, °Fltr, &quickFlag) < 0)
  51.     return (-1);
  52.  
  53. /* open input image */
  54.   imgI = ImageIn (argv[1]);
  55.   height = ImageGetHeight (imgI);
  56.   width = ImageGetWidth (imgI);
  57.   printf ("Input mage size is %dx%d.\n", width, height);
  58.  
  59. /* determine filter size and coefficients */
  60.   if (degFltr == 0.0)
  61.     cutoff = 100.0;
  62.   else
  63.     cutoff = 0.5 / (rSubsample * degFltr);
  64.   if (quickFlag)                /* rectangular filter window */
  65.     fltrSize = (long) (RECT_CUTOFF / cutoff + ROUNDUP);
  66.   else {                        /* Gaussian filter window */
  67.     stdDev = GAUSS_CUTOFF / cutoff;
  68.     fltrSize = (long) (3.0 / (2.0 * cutoff) + 0.5);
  69.   }
  70.   if ((fltrSize % 2) == 0)
  71.     fltrSize += 1;
  72.   printf ("Filter 3dB cutoff frequency is %5.2f and filter size is %dx%d.\n",
  73.           cutoff, fltrSize, fltrSize);
  74.  
  75.   if (!quickFlag) {
  76.     fltr = (long *) calloc (fltrSize, sizeof (*fltr));
  77.     midFltr = fltrSize / 2;
  78.     for (i = 0; i <= midFltr; i++)
  79.       fltr[i + midFltr] = fltr[midFltr - i]
  80.         = (long) (NORM * exp (-i * i / (2.0 * stdDev * stdDev)));
  81.   }
  82.  
  83. /* perform filtering */
  84.   imgO = ImageAlloc (height / rSubsample + 1, width / rSubsample + 1, 8);
  85.   if (quickFlag)
  86.     smoothr (imgI, imgO, fltrSize, rSubsample);
  87.   else
  88.     convolve1r (imgI, imgO, fltr, fltrSize, rSubsample);
  89.  
  90. /* output subsampled image */
  91.   printf ("Output image size is %dx%d.\n",
  92.           width / rSubsample + 1, height / rSubsample + 1);
  93.   ImageOut (argv[2], imgO);
  94.  
  95.   return (0);
  96. }
  97.  
  98.  
  99. /* USAGE:       function gives instructions on usage of program
  100.  *                    usage: usage (flag)
  101.  *              When flag is 1, the long message is given, 0 gives short.
  102.  */
  103.  
  104. long
  105. usage (flag)
  106.      short flag;                /* flag =1 for long message; =0 for short message */
  107. {
  108.  
  109. /* print short usage message or long */
  110.   printf ("USAGE: subsample inimg outimg [-r SAMPLE_RATE <%d>]\n", DFLT_SUBRATE);
  111.   printf ("                              [-d DEG_FILTERING <%3.1f>] [-q] [-L]\n", DFLT_DEG_FLTR);
  112.   if (flag == 0)
  113.     return (-1);
  114.  
  115.   printf ("\nsubsample performs subsampling after low-pass\n");
  116.   printf ("filtering on image; the default filter is a Gaussian\n\n");
  117.   printf ("ARGUMENTS:\n");
  118.   printf ("    inimg: input image filename (TIF)\n");
  119.   printf ("   outimg: output image filename (TIF)\n\n");
  120.   printf ("OPTIONS:\n");
  121.   printf ("    -r SAMPLE_RATE: rate of image reduction; the default setting\n");
  122.   printf ("                   -r %d reduces rate to reduce image by 2 in x and y).\n", DFLT_SUBRATE);
  123.   printf ("  -d DEG_FILTERING: value set between 0.0 and 1.0 controlling\n");
  124.   printf ("                    the degree of low-pass filtering; a value\n");
  125.   printf ("                    of 1.0 produces maximum filtering to reduce aliasing,\n");
  126.   printf ("                    but may lead to blurring;\n");
  127.   printf ("                    a value of 0.0 does no filtering at the risk of aliasing.\n");
  128.   printf ("                    the default is %3.1f.\n", DFLT_DEG_FLTR);
  129.   printf ("                -q: when set, performs quick low-pass filtering \n");
  130.   printf ("                    rectangular filter rather than Gaussian filter;\n");
  131.   printf ("                    the former is faster but doesn't produce equally\n");
  132.   printf ("                    good results as does the latter.\n");
  133.   printf ("                -L: print Software License for this module\n");
  134.   return (-1);
  135. }
  136.  
  137.  
  138. /* INPUT:       function reads input parameters
  139.  *                    usage: input (argc, argv, &rSubsample,
  140.  *                                              °Fltr, &quickFlag)
  141.  */
  142.  
  143. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  144.  
  145. long
  146. input (argc, argv, rSubsample, degFltr, quickFlag)
  147.      int argc;
  148.      char *argv[];
  149.      long *rSubsample;          /* subsample rate */
  150.      double *degFltr;           /* degree of filtering [0.0 - 1.0] */
  151.      short *quickFlag;          /* for quick and dirty rect. filter */
  152. {
  153.   long n;
  154.  
  155.   if (argc < 3)
  156.     USAGE_EXIT (-1);
  157.  
  158.   *rSubsample = DFLT_SUBRATE;
  159.   *degFltr = DFLT_DEG_FLTR;
  160.   *quickFlag = 0;
  161.  
  162.   for (n = 3; n < argc; n++) {
  163.     if (strcmp (argv[n], "-r") == 0) {
  164.       if (++n == argc || argv[n][0] == '-')
  165.         USAGE_EXIT (-1);
  166.       *rSubsample = atol (argv[n]);
  167.     }
  168.     else if (strcmp (argv[n], "-d") == 0) {
  169.       if (++n == argc || argv[n][0] == '-')
  170.         USAGE_EXIT (-1);
  171.       *degFltr = atof (argv[n]);
  172.     }
  173.     else if (strcmp (argv[n], "-q") == 0)
  174.       *quickFlag = 1;
  175.     else if (strcmp (argv[n], "-L") == 0) {
  176.       print_sos_lic ();
  177.       exit (0);
  178.     }
  179.     else
  180.       USAGE_EXIT (-1);
  181.   }
  182.  
  183.   return (0);
  184. }
  185.